"""
main.py - MicroPython 开机自动运行主程序示例（安全版本）

这个文件会在设备启动后自动执行（在 boot.py 之后）
上传到设备根目录（/main.py）后，每次重启都会自动运行

示例功能：板载 LED 闪烁（适用于 ESP32）

⚠️ 包含安全防护措施：
   - 启动延迟（可按 Ctrl+C 中断）
   - 安全模式检测（按住 BOOT 按钮跳过程序）
   - 异常处理（防止程序崩溃）
   - 循环延迟（避免 CPU 占满）
"""

from machine import Pin
import time
import sys

# ========== 配置区域 ==========
LED_PIN = 2          # ESP32 的板载 LED 通常在 GPIO 2
BLINK_INTERVAL = 0.5 # 闪烁间隔（秒）
SAFE_MODE_PIN = 0    # 安全模式按钮（ESP32 的 BOOT 按钮）
STARTUP_DELAY = 3    # 启动延迟（秒）

# ========== 安全防护函数 ==========
def check_safe_mode():
    """
    🛡️ 安全模式检测
    启动时按住 BOOT 按钮可以跳过 main.py 执行
    这样即使代码有问题也能进入 REPL 修复
    """
    try:
        button = Pin(SAFE_MODE_PIN, Pin.IN, Pin.PULL_UP)

        print("\n" + "=" * 50)
        print("🛡️ 安全模式检测中...")
        print("💡 提示：按住 BOOT 按钮可跳过 main.py")
        print("=" * 50)

        time.sleep(0.5)  # 给按钮检测一点时间

        if button.value() == 0:  # 按钮被按下（低电平）
            print("🚨 检测到 BOOT 按钮被按下")
            print("⏸️ 进入安全模式，跳过 main.py 执行")
            print("✅ 现在可以在 REPL 中修复问题")
            print("=" * 50)
            return True
    except Exception as e:
        print(f"⚠️ 安全模式检测失败: {e}")
        print("继续正常启动...")

    return False


def startup_delay():
    """
    ⏰ 启动延迟
    给用户足够时间按 Ctrl+C 中断程序
    这是防止设备"变砖"的重要安全措施
    """
    print("\n" + "=" * 50)
    print("⏳ 程序即将启动...")
    print("💡 提示：按 Ctrl+C 可以中断程序")
    print("=" * 50)

    for i in range(STARTUP_DELAY, 0, -1):
        print(f"⏱️  倒计时: {i} 秒")
        time.sleep(1)

    print("▶️ 开始运行主程序...\n")


# ========== 主程序 ==========
def main():
    """
    主程序函数
    """
    print("=" * 40)
    print("MicroPython Auto-Run Example")
    print("LED Blink on GPIO", LED_PIN)
    print("=" * 40)

    # 初始化 LED 引脚
    led = Pin(LED_PIN, Pin.OUT)

    # 闪烁计数器
    count = 0

    try:
        # 无限循环：让 LED 不断闪烁
        while True:
            # LED 开
            led.on()
            print(f"LED ON  - Count: {count}")
            time.sleep(BLINK_INTERVAL)

            # LED 关
            led.off()
            print(f"LED OFF - Count: {count}")
            time.sleep(BLINK_INTERVAL)

            count += 1

    except KeyboardInterrupt:
        # 按 Ctrl+C 时优雅退出
        print("\n程序被用户中断")
        led.off()  # 确保 LED 关闭
        print("LED 已关闭，程序退出")

    except Exception as e:
        # 捕获其他异常，避免程序崩溃
        print(f"发生错误: {e}")
        led.off()


# ========== 程序入口 ==========
if __name__ == "__main__":
    try:
        # 🛡️ 第一道防线：安全模式检测
        if check_safe_mode():
            sys.exit()  # 跳过程序执行

        # ⏰ 第二道防线：启动延迟
        startup_delay()

        # ▶️ 执行主程序
        main()

    except KeyboardInterrupt:
        # 用户主动中断（Ctrl+C）
        print("\n" + "=" * 50)
        print("⏸️ 程序被用户中断")
        print("=" * 50)

    except Exception as e:
        # 捕获所有未处理的异常，防止设备崩溃
        print("\n" + "=" * 50)
        print("❌ 程序发生严重错误")
        print("=" * 50)
        print(f"错误信息: {e}")
        print("\n📋 错误详情:")
        sys.print_exception(e)
        print("\n💡 提示：程序已安全退出，可以在 REPL 中修复问题")
        print("=" * 50)


# ========== 使用说明 ==========
"""
📝 如何上传并实现开机自动运行：

1. 使用 VS Code MicroPython 插件：
   - 右键点击此文件
   - 选择 "Upload File to Device"
   - 输入路径：/main.py（必须是根目录！）

2. 重启设备：
   - 按下开发板的 Reset 按钮，或
   - 在 REPL 中输入：import machine; machine.reset()

3. 观察效果：
   - 设备重启后 LED 会自动开始闪烁
   - 通过 REPL 终端可以看到输出信息

4. 停止程序：
   - 在 REPL 终端按 Ctrl+C
   - 或者删除设备上的 /main.py 文件

⚠️ 重要提示：
- 文件名必须是 main.py（小写）
- 必须上传到根目录 /
- 如果是其他开发板，可能需要修改 LED_PIN 的值
  * ESP32: 通常是 GPIO 2
  * ESP8266: 通常是 GPIO 2 或 GPIO 16
  * Raspberry Pi Pico: 通常是 GPIO 25

💡 调试技巧：
- 先用 "Run File on Device" (Ctrl+Shift+R) 测试代码
- 确认无误后再上传到 /main.py
- 上传后可以立即在 REPL 看到程序运行的输出

🛡️ 安全功能说明：

1. **启动延迟（3秒）**
   - 上传后重启设备
   - 在倒计时期间快速按 Ctrl+C 可中断程序
   - 这样即使代码有问题也能及时阻止

2. **安全模式（BOOT按钮）**
   - 启动时按住 BOOT 按钮
   - 程序会自动跳过执行
   - 进入 REPL 可以删除或修复文件

3. **异常保护**
   - 所有代码都在 try-except 中
   - 即使出错也会优雅退出
   - 不会导致设备崩溃或无响应

4. **循环延迟**
   - 每次循环都有 time.sleep()
   - 不会占满 CPU
   - 保证 REPL 能正常响应

📖 更多安全信息请查看：SAFETY_GUIDE.md
"""
